package com.istock.union.user.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.istock.base.enumration.Enums;
import com.istock.union.user.client.SSOClientUtils;
import com.istock.union.user.dao.DeptInfoMapper;
import com.istock.union.user.dao.UserInfoMapper;
import com.istock.union.user.model.Constants;
import com.istock.union.user.model.DeptInfo;
import com.istock.union.user.model.DeptInfoExample;
import com.istock.union.user.model.TenantInfo;
import com.istock.union.user.model.UserInfoExample;
import com.istock.union.user.service.DeptInfoService;
import com.istock.union.user.service.TenantInfoService;

@Repository
public class DeptInfoServiceImpl implements DeptInfoService{

	@Autowired
	private DeptInfoMapper deptInfoMapper;
	
	@Autowired
	private UserInfoMapper userInfoMapper;
	
	@Autowired
	private TenantInfoService tenantInfoService;
	
	@Value("${multiple.corporate:false}")
	private boolean multipleCorporate;
	
	/**
	 * 根据条件查询组织机构信息
	 * 
	 * @param deptInfo
	 * @return
	 */
	public List<DeptInfo> selectByExampleNameLike(DeptInfo deptInfo) {
		DeptInfoExample example = new DeptInfoExample();
		DeptInfoExample.Criteria criteria = example.createCriteria();
		
		if(deptInfo != null) {
			
			if (StringUtils.isNotBlank(deptInfo.getDeptName())) {
				criteria.andDeptNameLike("%" + deptInfo.getDeptName() + "%");
			}
		}
		
		example.setOrderByClause(" ID DESC ");
		return deptInfoMapper.selectByExample(example);
	}
	
	/**
	 * 插入组织机构信息
	 * 
	 * @param deptInfo
	 * @return
	 */
	public int insertDept(DeptInfo deptInfo) {
		deptInfo.setDelFlag(Enums.getInstance().getEnumsValueByCode("COMMON_BOOL", "COMMON_BOOL_YES"));
		deptInfo.setAncestors(findAncestorsOfParent(deptInfo));
		deptInfo.setCreateTime(new Date());
		return deptInfoMapper.insertSelective(deptInfo);
	}
	
	//获取部门的级联编号
	private String findAncestorsOfParent(DeptInfo dept) {
		if(StringUtils.isNotBlank(dept.getParentId())) {
			DeptInfo parent = deptInfoMapper.selectByPrimaryKey(dept.getParentId());
			if(parent ==  null ) {
				return dept.getDeptCode();
			}
			
			if(StringUtils.isNotBlank(parent.getAncestors())) {
				return parent.getAncestors() + "," + dept.getDeptCode();
			}
		}
		return dept.getDeptCode();
	}
	
	/**搜索路径下的所有的机构
	 * @param ancestor
	 * @param currentDeptCode 如果存在,过滤当前的机构,只查询父的
	 * @return
	 */
	public List<DeptInfo> findAncestorDept(String ancestor , String currentDeptCode){
		if(StringUtils.isNotBlank(ancestor)) {
			DeptInfoExample example = new DeptInfoExample();
			DeptInfoExample.Criteria criteria = example.createCriteria();
			if (StringUtils.isNotBlank(ancestor)) {
				criteria.andDeptCodeIn(Arrays.asList(ancestor.split(",")));
			}
			if(StringUtils.isNotBlank(currentDeptCode)) {
				criteria.andDeptCodeNotEqualTo(currentDeptCode);
			}
			return deptInfoMapper.selectByExample(example);
		}
		return null;
	}
	
	/**
	 * 更新组织机构信息
	 * 
	 * @param menu
	 * @return
	 */
	@Transactional
	public int updateDept(DeptInfo dept) {
		//查询所有的子节点
		DeptInfo parentDept = selectDeptById(dept.getParentId());
		StringBuffer newAncestor = new StringBuffer();
		if(parentDept != null) {
			newAncestor.append(parentDept.getAncestors()).append(",");
		}
		newAncestor.append(dept.getDeptCode());
		
		DeptInfo currentDept = selectDeptById(dept.getId());
		
		//用原有的ancestor去查子
		DeptInfoExample example = new DeptInfoExample();
		DeptInfoExample.Criteria criteria = example.createCriteria();
		criteria.andAncestorsLike(currentDept.getAncestors()+",%");
		criteria.andDelFlagEqualTo(Constants.COMMON_VALID);
		List<DeptInfo> deptList = deptInfoMapper.selectByExample(example);
		if(deptList != null) {
			//级联更新子节点的ancestor
			for(DeptInfo deptInfo : deptList) {
				DeptInfo target = new DeptInfo();
				StringBuffer ancestor = new StringBuffer(newAncestor);
				ancestor.append(",").append(deptInfo.getDeptCode());
				target.setAncestors(ancestor.toString());
				target.setUpdateBy(dept.getUpdateBy());
				target.setUpdateTime(new Date());
				target.setId(deptInfo.getId());
				deptInfoMapper.updateByPrimaryKeySelective(target);
			}
		}
		
		dept.setAncestors(newAncestor.toString());
		dept.setUpdateTime(new Date());
		int result = deptInfoMapper.updateByPrimaryKeySelective(dept);
		// 如果该组织机构是启用状态，则启用该组织机构的所有上级组织机构
//		updateParentDeptStatus(dept);
		return result;
	}

	/**
	 * 统计子组织机构数量
	 * 
	 * @param parentId
	 * @return
	 */
	public long countDeptByParentId(String parentId) {
		DeptInfoExample example = new DeptInfoExample();
		example.createCriteria().andParentIdEqualTo(parentId).andDelFlagEqualTo(Constants.COMMON_VALID);
		return deptInfoMapper.countByExample(example);
	}

	/**
	 * 统计组织机构下用户数量
	 * 
	 * @param deptId
	 * @return
	 */
	public long countUsersByDeptId(String deptId) {
		UserInfoExample example = new UserInfoExample();
		example.createCriteria().andDeptCodeEqualTo(deptId).andStatusEqualTo(Constants.COMMON_VALID);;
		return userInfoMapper.countByExample(example);
	}

	/**
	 * 根据组织机构ID删除组织机构信息
	 * 
	 * @param id
	 * @return
	 */
	public int deleteDeptById(String id) {
		// 并不实际删除数据，只是将标识更改为无效
		DeptInfo dept = new DeptInfo();
		dept.setId(id);
		dept.setDelFlag(Constants.COMMON_INVALID);
		dept.setUpdateBy(SSOClientUtils.getInstance().findCurrentUser().getUserName());
		dept.setUpdateTime(new Date());
		return deptInfoMapper.updateByPrimaryKeySelective(dept);
	}

	/**
	 * 检查组织机构名称是否唯一
	 * id可以为空
	 * 
	 * @param deptInfo
	 * @return
	 */
	public Boolean checkDeptNameUnique(String parentId , String deptName , String id) {
		DeptInfoExample example = new DeptInfoExample();
		DeptInfoExample.Criteria criteria = example.createCriteria();
		criteria.andParentIdEqualTo(parentId);
		criteria.andDeptNameEqualTo(deptName);
		if (StringUtils.isNotBlank(id)) {
			criteria.andIdNotEqualTo(id);
		}
		return deptInfoMapper.countByExample(example) == 0;
	}
	
	/**检查组织code在全表唯一
	 * @param id
	 * @param deptCode
	 * @return
	 */
	public Boolean checkDeptCodeUnique(String id , String deptCode) {
		DeptInfoExample example = new DeptInfoExample();
		DeptInfoExample.Criteria criteria = example.createCriteria();
		criteria.andDeptCodeEqualTo(deptCode);
		if (StringUtils.isNotBlank(id)) {
			criteria.andIdNotEqualTo(id);
		}
		return deptInfoMapper.countByExample(example) == 0;
	}
	
	/**列出组织机构树
	 * 在很多场景下,需要列出组织机构树,请使用统一的方法
	 * @param tenantId 当前的租户,可以为空
	 * @param userDeptId 当前的用户登录的机构,可以为空
	 * @param isAdmin 当前登录用户是否为admin用户,如果是,则在树上增加租户信息
	 * @param tenantSelect 租户是否可选
	 * @return
	 */
	public List<Map<String , Object>> queryDeptTreeData(String tenantId , String userDeptCode , boolean isAdmin , boolean tenantSelect){
		DeptInfoExample example = new DeptInfoExample();
		DeptInfoExample.Criteria criteria = example.createCriteria();
		if(StringUtils.isNotBlank(tenantId)) {
			criteria.andTenantCodeEqualTo(tenantId);
		}
		//如果传入userDeptId,只查询当前部门和当前部门以下的部门
		if(StringUtils.isNotBlank(userDeptCode)) {
			DeptInfo deptInfo = selectDeptByCode(userDeptCode);
			if(deptInfo != null) {
				//criteria.andAncestorsEqualTo(deptInfo.getAncestors());
				criteria.andAncestorsLike(deptInfo.getAncestors()+"%");
			}
		}
		criteria.andDelFlagEqualTo(Constants.COMMON_VALID);
		example.setOrderByClause(" CREATE_TIME DESC");
		List<DeptInfo> list = deptInfoMapper.selectByExample(example);
		
		//如果是超级管理员登录
		List<TenantInfo> tenantList = null;
		if(isAdmin) {
			tenantList = tenantInfoService.findAllTenantList();
		}
		return generateZtreeData(list, tenantList,tenantSelect);
	}
	
	/**生成满足ztree树要求的数据
	 * @param deptList 机构数据
	 * @param tenantInfoList 租户数据
	 * 当存在机构数据的时候,对deptList的根节点进行修改,将dept绑定在租户上
	 * @return
	 */
	private List<Map<String , Object>> generateZtreeData(List<DeptInfo> deptList , List<TenantInfo> tenantInfoList, boolean tenantSelect){
		List<Map<String, Object>> trees = new ArrayList<Map<String, Object>>(10);
		
		if(tenantInfoList != null && tenantInfoList.size()>0) {
			for(TenantInfo tenantInfo : tenantInfoList) {
				Map<String, Object> deptMap = new HashMap<String, Object>();
				deptMap.put("id", tenantInfo.getTenantCode());
				deptMap.put("tenantCode", tenantInfo.getTenantCode());
				deptMap.put("pId", "0");
				deptMap.put("nodeType", "tenant");
				deptMap.put("name", tenantInfo.getTenantName());
				deptMap.put("title", tenantInfo.getTenantName());
				deptMap.put("value", tenantInfo.getTenantCode());
				if(!tenantSelect) {
					deptMap.put("nocheck", true);
				}
				trees.add(deptMap);
			}
		}
		for (DeptInfo dept : deptList) {
			Map<String, Object> deptMap = new HashMap<String, Object>();
			deptMap.put("id", dept.getId());
			
			if("0".equals(dept.getParentId()) && tenantInfoList != null && tenantInfoList.size()>0) {
				TenantInfo tenantInfo = findTenantInfoByCode(tenantInfoList , dept.getTenantCode());
				if(tenantInfo!= null) {
					deptMap.put("pId", tenantInfo.getTenantCode());
				}
			}
			
			if(!deptMap.containsKey("pId")) {
				deptMap.put("pId", dept.getParentId());
				
			}
			deptMap.put("nodeType", "dept");
			deptMap.put("name", dept.getDeptName());
			deptMap.put("tenantCode", dept.getTenantCode());
			deptMap.put("title", dept.getDeptName());
			deptMap.put("value", dept.getDeptCode());
			trees.add(deptMap);
		}
		return trees;
	}
	
	/**在租户列表里面寻找code的租户信息
	 * @param tenantList
	 * @param tenantCode
	 * @return
	 */
	private TenantInfo findTenantInfoByCode(List<TenantInfo> tenantList , String tenantCode) {
		if(tenantList != null && tenantList.size()>0 && StringUtils.isNotEmpty(tenantCode)) {
			for(TenantInfo item : tenantList) {
				if(item.getTenantCode().equals(tenantCode)) {
					return item;
				}
			}
		}
		return null;
	}
	
	public List<DeptInfo> queryDeptTree(String tenantId , String userDeptId , String deptName , String deptCode){
		DeptInfoExample example = new DeptInfoExample();
		DeptInfoExample.Criteria criteria = example.createCriteria();
		if(StringUtils.isNotBlank(tenantId)) {
			criteria.andTenantCodeEqualTo(tenantId);
		}
		
		if(StringUtils.isNotBlank(deptName))
		{
			criteria.andDeptNameLike("%"+deptName + "%");
		}
		if(StringUtils.isNotBlank(deptCode)) {
			criteria.andDeptCodeLike("%"+deptCode + "%");
		}
		
		//如果传入userDeptId,只查询当前部门和当前部门以下的部门
		if(StringUtils.isNotBlank(userDeptId)) {
			DeptInfo deptInfo = selectDeptById(userDeptId);
			if(deptInfo != null) {
				//criteria.andAncestorsEqualTo(deptInfo.getAncestors());
				criteria.andAncestorsLike(deptInfo.getAncestors()+"%");
			}
		}
		criteria.andDelFlagEqualTo(Constants.COMMON_VALID);
		example.setOrderByClause(" ID ASC");
		return deptInfoMapper.selectByExample(example);
	}
	
	/**
	 * 对象转组织机构树
	 *
	 * @param deptList 组织机构列表
	 * @param isCheck 是否需要选中
	 * @param roleDeptList 角色已存在菜单列表
	 * @return
	 */
	public List<Map<String, Object>> getTrees(List<DeptInfo> deptList, boolean isCheck, List<String> roleDeptList) {
		List<Map<String, Object>> trees = new ArrayList<Map<String, Object>>(10);
		List<String> ids = new ArrayList<String>(10);
		for (DeptInfo dept : deptList) {
			Map<String, Object> deptMap = new HashMap<String, Object>();
			ids.add(dept.getId());
			deptMap.put("id", dept.getId());
			deptMap.put("pId", dept.getParentId());
			deptMap.put("name", dept.getDeptName());
			deptMap.put("title", dept.getDeptName());
			if (isCheck) {
				deptMap.put("checked", roleDeptList.contains(dept.getId() + dept.getDeptName()));
			} else {
				deptMap.put("checked", false);
			}
			trees.add(deptMap);
		}
		for (Map<String, Object> map : trees) {
			if (!ids.contains(map.get("pId"))) {
				map.put("pId", "0");
			}
		}
		return trees;
	}

	/**
	 * 根据组织机构主键查询组织机构信息
	 * 
	 * @param id
	 * @return
	 */
	public DeptInfo selectDeptById(String id) {
		return deptInfoMapper.selectByPrimaryKey(id);
	}
	
	public DeptInfo selectDeptByCode(String deptCode) {
		DeptInfoExample example = new DeptInfoExample();
		example.createCriteria().andDeptCodeEqualTo(deptCode);
		List<DeptInfo> deptList = deptInfoMapper.selectByExample(example);
		if(deptList != null && deptList.size()>0) {
			return deptList.get(0);
		}
		return null;
	}

	/**
	 * 
	 * @param tenantId
	 * @return
	 */
	public Boolean checkNoSon(String tenantId) {
		DeptInfoExample example = new DeptInfoExample();
		example.createCriteria().andTenantCodeEqualTo(tenantId);
		return deptInfoMapper.countByExample(example) == 0;
	}

	/**
	 * 根据ID集合查询所有无效的组织机构
	 * 
	 * @param ids
	 * @return
	 */
	public long countInvalidDeptListByIds(List<String> ids) {
		DeptInfoExample example = new DeptInfoExample();
		example.createCriteria().andIdIn(ids).andDelFlagEqualTo(Constants.COMMON_INVALID);
		return deptInfoMapper.countByExample(example);
	}

	/**
	 * 根据ID统计符合状态的子集机构
	 * 
	 * @param id
	 * @param status
	 * @return
	 */
	public long countDeptByAncestorId(String id, Integer status) {
		DeptInfoExample example = new DeptInfoExample();
		DeptInfoExample.Criteria criteria = example.createCriteria();
		criteria.andAncestorsLike("%," + id + "%");
		criteria.andDelFlagEqualTo(Constants.COMMON_INVALID);
		return deptInfoMapper.countByExample(example);
	}
}
